package org.itsolutions.javaBackup.buffers;

import static org.itsolutions.javaBackup.definitions.Count.THOUSAND;

import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.itsolutions.javaBackup.definitions.Count;
import org.itsolutions.javaBackup.logger.ELogLevel;
import org.itsolutions.javaBackup.logger.ILogger;
import org.itsolutions.javaBackup.logger.LoggerHelper;
import org.itsolutions.javaBackup.spi.common.io.EBufferUID;
import org.itsolutions.javaBackup.spi.common.io.IBuffer;
import org.itsolutions.javaBackup.spi.common.io.ISharedBuffer;

import com.google.inject.Inject;

/**
 * Class used as central controller for all the buffers in the node. It should increase/decrease buffer sizes of newly created ones dynamicly.
 * @author Tomas Fecko
 */
public final class SharedBufferProvider implements ISharedBuffer {

	private static final ILogger				LOGGER = LoggerHelper.getLogger(SharedBufferProvider.class);
	private final Map<EBufferUID, IBuffer<?>>	mSingletonsBuffers;
	private final Map<String, IBuffer<?>>		mCreatedBuffers = new ConcurrentHashMap<String, IBuffer<?>>();
	
	/**
	 * 
	 */
	@Inject SharedBufferProvider() {
		mSingletonsBuffers = Collections.synchronizedMap(new EnumMap<EBufferUID, IBuffer<?>>(EBufferUID.class));
		for (EBufferUID bufferUID : EBufferUID.values()) {
			mSingletonsBuffers.put(bufferUID, new JBBuffer<Object>(this, UUID.randomUUID().toString(), 
					Count.TWENTY_THOUSAND)); //TODO finish - put dynamic size
		}
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> IBuffer<T> getSingletonBuffer(EBufferUID pBufferUID) {
		try {
			return (IBuffer<T>) mSingletonsBuffers.get(pBufferUID);
		} catch (ClassCastException e) {
			LOGGER.log(ELogLevel.ERROR, e);
			throw e;
		}		
	}

	@Override
	public <T> IBuffer<T> createBuffer(Class<T> pItemType, int pMaxSize) {
		String bufferUID = UUID.randomUUID().toString();
		JBBuffer<T> buffer = new JBBuffer<T>(this, bufferUID, pMaxSize); //TODO finish - put dynamic size
		mCreatedBuffers.put(bufferUID, buffer);
		return buffer;
	}

	@Override
	public <T> IBuffer<T> createBuffer(Class<T> pItemType) {
		String bufferUID = UUID.randomUUID().toString();
		JBBuffer<T> buffer = new JBBuffer<T>(this, bufferUID, THOUSAND); //TODO finish - put dynamic size
		mCreatedBuffers.put(bufferUID, buffer);
		return buffer; 		
	}

	@Override
	public <T> IBuffer<T> createBuffer(int pMaxSize) {
		String bufferUID = UUID.randomUUID().toString();
		JBBuffer<T> buffer = new JBBuffer<T>(this, bufferUID, pMaxSize); //TODO finish - put dynamic size
		mCreatedBuffers.put(bufferUID, buffer);
		return buffer;
	}

	/**
	 * 
	 * @param pBufferUID bufferID
	 */
	public void dispose(String pBufferUID) {
		IBuffer<?> removed = mCreatedBuffers.remove(pBufferUID);
		if (removed != null) {
			removed.clear();
		}
	}
}








